import pymongo
from server.util import *

'''
FlaskServer的数据库管理。
'''


class FlashDatabase:
    START_PORT: 23001
    def __init__(self):
        self.conn = pymongo.MongoClient()
        self.db = self.conn.flashserver
    '''
    添加app
    :param data:应用数据。应该符合最小数据格式。
    - 库：应用信息(app_info)：这部分请放在flashserver.json里面
        - 应用名字(name)：用来调用的名字
        - 展示名字(display_name)：显示在面板上的名字
        - 运行命令(command)：字符串，一般直接`python3 simple.py`
        - 应用运行类型(run_mode)
            - 热启动型(hot_start)：需要时候启动，没有持续的数据连接则关闭
            - 常驻型(stand_by)：一直运行
            - 按需启动型(once_start)：每次访问只启动一次
        - 运行计划任务(task)
            - 定时执行(regular)
            - API调用执行(...)：暂时不可用
        - 版本信息(version_info)
            - 所有者(owner)
            - 更新时间(update_time)
            - 版本(version)
            - 依赖库(requirements)数组
            - 提交注释(comments)
    - 库：应用运行(app_running)
        - 应用运行记录(logs)
            - 日志类型(type)：【启动(launch)，访问(visit)，错误(error)】
            - 日志内容(content)
        - 应用运行状况(status)
            - 运行状态(status)：【运行中(running)，正在操作(in_operation)，
                                  挂起(hang_up)，停机(stop)，故障(error)】
    - 运行管理(manager)
        - 当前可用最小端口号(min_port)
    :returns True:成功, False: 失败
    '''
    def set_app_new(self, data):
        if not app_info_check(data):
            return False
        self.db.app_info.insert_one(data)
        return True

    def get_app_info(self, name: str):
        data = list(self.db.app_info.find({'info.name': {'$eq': name}}))
        print(data)
        if len(data) == 0:
            return None
        return data[0]

    # 登记程序运行情况
    def set_running_update(self, name: str):
        data = self.get_app_info(name)
        if data is None:
            return False

    # 获取最小端口号
    def get_min_port(self):
        data = list(self.db.manager.find({'min_port': {'$exists': True}}))
        min_port = self.START_PORT
        if len(data) == 0:
            # 直接初始化
            self.db.manager.insert_one({'min_port': self.START_PORT})
            return min_port
        min_port = data[0]['min_port']
        return min_port

    # 返回当前可用并且更新
    def update_min_port(self):
        min_port = self.get_min_port()
        self.db.manager.update({'min_port': min_port}, {'$set': {'min_port': min_port+1}})
        return min_port

